#!/usr/bin/perl -w
#
# Skrypt wysyłający wiadomości SMS do wszystkich polskich sieci 
# poprzez bramkę SMS zarejestrowanych użytkowników Orange (mBox)
#
# Wymaga: perl + LWP + SSL (perl-libwww/libwwwperl, perl-crypt-SSLeay).
# Wymagana autoryzacja użytkownika
#
# (c) 2003-2009 Jacek Fiok <jfiok@jfiok.org>; http://sms.jfiok.org
#
# Treść wiadomości: do 640 znaków; wszystkie polskie sieci.
#
# Podziękowania dla:
# - Spley <sms@spley.home.pl>
# - Maciej Krzyżanowski <spider@popnet.pl>
# - Łukasz Górowski <lukasz@gorowski.com>
#
# Przeróbka po przekształceniu sieci Idea w Orange:
# - Rafał 'RaV.' Matczak <matczak.rafal.orangutan.gmail.com>

my $VERSION = "2012041901";

use strict;
use HTTP::Request::Common;
use HTTP::Cookies;
use LWP::UserAgent;
use Crypt::SSLeay;

# --- DEBUG ---
my $debug = 0; # 0:no, 1:yes
# use LWP::Debug qw(+ -conns);
# LWP::Debug::trace('send()');
sub debug { if ($debug) { print "[", shift, "]\n"; } }

# --- COOKIES ---

##
my $ckey = "";
my $cval = "";
my $cookie_jar = HTTP::Cookies->new;

sub cookieScanner {
	# my $i; for ($i=0; $i<5; $i++) { print $i, " : ", $_[$i], "\n"; }
	($ckey eq $_[1]) and $cval = $_[2]; 
}

sub getCookie {
	$cval = "";
	$ckey = shift;
	$cookie_jar->scan (\&cookieScanner);
	return $cval;
}

# --- User Agent ---

my $ua = new LWP::UserAgent;
$ua->timeout(30);
$ua->agent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/534.55.3 (KHTML, like Gecko) Version/5.1.5 Safari/534.55.3");
#$ua->env_proxy();
$ua->cookie_jar($cookie_jar);

# --- functions() ---

## zero set
my $res; my $req; # response; request

sub error {
	my ($text, $return) = @_;
	print "[ERROR] $text (#$return)\n";
	exit $return;
}

sub visit {
	$res = $ua->request (GET $_[0]);
	if (!($res->is_success)) { error ($_[1], $_[2]); }
}

# --- main() ---

select(STDERR); $| = 1; # make unbuffered
select(STDOUT); $| = 1; # make unbuffered

if ($#ARGV != 3 ) { error ("Zła ilość parametrów - podaj numer i treść wiadomości", 6); }

my $number = $ARGV[0];
my $text = $ARGV[1];
my $username = $ARGV[2];
my $password = $ARGV[3];

$number =~ s/^\+48//;
$number =~ s/^00//;

# allow redirect (POST)
push @{ $ua->requests_redirectable }, 'POST';

# --- DO IT! ---

visit ("https://www.orange.pl/zaloguj.phtml", 
       "Błąd podczas otwierania formularza [1]", 1);

my $action = 'https://www.orange.pl/zaloguj.phtml?_DARGS=/ocp/gear/infoportal/portlets/login/login-box.jsp';

debug ("Wysyłanie formularza logowania: ".$action);
$req = POST $action, [
	"_dyncharset"=>"UTF-8",
	"_dynSessConf"=>"-7322242883615328119",
	"/tp/core/profile/login/ProfileLoginFormHandler.loginErrorURL"=>"https://www.orange.pl/zaloguj.phtml",
	"_D:/tp/core/profile/login/ProfileLoginFormHandler.loginErrorURL"=>"",
	"/tp/core/profile/login/ProfileLoginFormHandler.loginSuccessURL"=>"",
	"_D:/tp/core/profile/login/ProfileLoginFormHandler.loginSuccessURL"=>"",
	"/tp/core/profile/login/ProfileLoginFormHandler.firstEnter"=>"true",
	"_D:/tp/core/profile/login/ProfileLoginFormHandler.firstEnter"=>"",
	"/tp/core/profile/login/ProfileLoginFormHandler.value.login"=>$username,
	"_D:/tp/core/profile/login/ProfileLoginFormHandler.value.login"=>"",
	"/tp/core/profile/login/ProfileLoginFormHandler.value.password"=>$password,
	"_D:/tp/core/profile/login/ProfileLoginFormHandler.value.password"=>"",
	"/tp/core/profile/login/ProfileLoginFormHandler.rememberMe"=>"false",
	"_D:/tp/core/profile/login/ProfileLoginFormHandler.rememberMe"=>"",
	"/tp/core/profile/login/ProfileLoginFormHandler.login"=>"Zaloguj się",,
	"_D:/tp/core/profile/login/ProfileLoginFormHandler.login"=>"",
	"_DARGS" => "/ocp/gear/infoportal/portlets/login/login-box.jsp"
];

$req->referer ("https://www.orange.pl/zaloguj.phtml");
$res = $ua->request($req);
if (! ($res->is_success)) { error ("Błąd podczas logowania [2]", 1); }

if (! ($res->content !~ /login-box__title/) ) { error ("Błąd podczas logowania - sprawdź poprawność wprowadzonego hasła", 5); } 

debug ("Logowanie zakończone powodzeniem");

$req = GET 'https://www.orange.pl/portal/map/map/message_box?mbox_view=newsms&mbox_edit=new';
$res = $ua->request($req);

debug ("Sprawdzam ilość pozostałych do wykorzystania wiadomości");
my $left = -1;

if ($res->content =~ /<span class=\"label\">bezp.*?atne.*?:<\/span>.*?<span class=\"value\">([0-9]+).*?<\/span>.*?<span class=\"label\">z doładowa.*?:<\/span>.*?<span class=\"value\">([0-9]+)<\/span>/sm) {
	$left = eval ($1) + eval ($2);
} elsif ($res->content =~ /<span class=\"label\">bezp.*?atne.*?:<\/span>.*?<span class=\"value\">([0-9]+)<\/span>/sm) {
	$left = eval ($1);
}

if ($left == -1) { error ("Nie mogę odczytać ilości dostępnych wiadomości SMS", 7); }
if ($left == 0) { error ("Wykorzystano limit wiadomości w tym miesiącu", 3); }

debug ("Pobieram token");
##
my $token;

if ($res->content =~ /<input name="\/amg\/ptk\/map\/messagebox\/formhandlers\/MessageFormHandler.token" value="([a-zA-Z0-9]{1,15})" type="hidden"\/>/sm) { $token=$1; };
if (!$token) { error ("Token nie został pobrany prawidłowo",1);}
debug ("Token " . $token);

debug ("Rozpoczynam wysyłanie formularza wiadomości SMS");
$req = POST 'https://www.orange.pl/portal/map/map/message_box?_DARGS=/gear/mapmessagebox/smsform.jsp', [
	'_dyncharset' => "UTF-8",
	'/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.type' => "sms",
	'_D:/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.type' => " ",
	'/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.errorURL' => '/portal/map/map/message_box?mbox_view=newsms',
	'_D:/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.errorURL'  => " ",
	'/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.successURL' => '/portal/map/map/message_box?mbox_view=sentmessageslist',
	'_D:/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.successURL' => " ",
	'/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.to' => $number,
	'_D:/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.to' => " ",
	'_D:/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.body' => " ",
	'/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.body' => $text,
	'/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.token' => $token,
	'_D:/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.token' => ' ',
	'enabled' => "true",
	'counter' => (640 - length($text)),
	'/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.create.x' => 0,
	'/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.create.y' => 0,
	'_D:/amg/ptk/map/messagebox/formhandlers/MessageFormHandler.create' => " ",
	'_DARGS' => '/gear/mapmessagebox/smsform.jsp'
];
$req->referer('https://www.orange.pl/portal/map/map/message_box?mbox_edit=new&mbox_view=newsms');
# Where the magic happens!
$res = $ua->request($req);
if (!($res->is_success)) { error ("Błąd podczas wysyłania wiadomości SMS", 1);}

debug ("Sprawdzam ilość pozostałych wiadomości SMS po przesłaniu formularza wysyłania wiadomości");
##
my $right = -1;

if ($res->content =~ /<span class="label">bezp.*?atne.*?:<\/span>.*?<span class="value">([0-9]+).*<span class="label">z do.*?adowa.*?:<\/span>.*?<span class="value">([0-9]+)/sm) {
	$right = eval ($1) + eval ($2);
} elsif ($res->content =~ /<span class=\"label\">bezp.*?atne.*?<\/span>.*?<span class=\"value\">([0-9]+)<\/span>/sm) {
	$right = eval ($1);
}

if ($right == -1) { error ("Nie mogę odczytać ilości pozostałych po wysłaniu wiadomości SMS", 7); }

# --- report() ---

if ($res->content =~ /Niepoprawny numer telefonu/) { error ("Podano niepoprawny numer telefonu", 2); }

if ($left > $right) {
	print "[OK] Wszystko w porządku; pozostały limit wiadomości: ".$right."\n";
	exit 0; 
} else {
	error ("Możliwy błąd podczas wysyłania (raportowane limity - przed wysłaniem: ".$left.", po wysłaniu: ".$right.").", 8);
}


###  DEPRECATED  ###
#my $mode = 0; # raport doręczenia 0:nie 1:tak
#my $seconds = 0; # sprawdź raport po X sekundach

my %answers = (
        "Skrzynka wiadomości" => ["Wszystko OK", 0],
        "Zły numer" => ["Zły numer!", 2],
        "został wyczerpany" => ["Limit wiadomości na dziś przekroczony!", 3]
);

sub analizeResults {
        my $res = $_[0];
        my $searchString;
        my @val;
        while ( ($searchString, @val) = each (%answers) ) {
          if ($res =~ /$searchString/ ) {
                  print $answers{$searchString}[0], "\n";
                  exit $answers{$searchString}[1];
          }
        }
        print "Nieoczekiwany błąd:\n$res\n";
        exit 127;
}
###  end DEPRACATED ###
